Audit SEO automatically with Lighthouse CI - #107
Merged
Conversation
Issue #35 asks for an open source tool that tests SEO appropriateness, for that tool to run periodically, and only then for the code to be improved according to what it reports. This does the first three and acts on the findings of the fourth. Lighthouse is the tool. `.lighthouserc.json` runs its SEO category against seven representative pages — the homepage, about, the tag index, one tag page, two posts and a post under the book/review categories — and asserts a perfect category score. A new workflow runs it on every pull request and on a weekly cron, since search engines change what they reward without any commit on our side. Three things this turned up while being set up. The audit has to build the way pages.yml does. A development build has no `site.url`, which leaves `rel=canonical` relative and robots.txt without a sitemap line; Lighthouse scored those pages 0.83 while production scored 100. The workflow therefore builds with the production config. Autodiscovery is not enough. Pointed at `_site` it collects `index.html` files only, so all twelve posts — the pages whose SEO actually matters — went unaudited. The URLs are listed explicitly instead. Listing post URLs meant pinning the timezone. Jekyll derives permalinks from the post date in local time, so `2019-01-13 01:23:12 +0530` builds to /2019/01/12/ on a UTC runner and /2019/01/13/ on a machine in IST. The same commit produced different URLs depending on where it was built. Setting `timezone: UTC` makes local builds agree with CI; all twelve live post URLs were checked against the deployed site and none of them change. The audit then reported two links whose text does not describe the target, "this" and "here". Both are reworded, which brings every audited page to 100. Closes #35 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What #35 actually asked for
Three of the four sub-tasks are about tooling, and only the last is about changing code — and it is explicitly downstream of what the tool reports. So the tool comes first here, and the code changes are whatever it flagged.
The tool
Lighthouse via
@lhci/cli, both open source..lighthouserc.jsonruns its SEO category against seven representative pages — homepage, about, tag index, one tag page, two posts, and a post under thebook/reviewcategories — and asserts a perfect score.A new
SEO auditworkflow runs it on every pull request and on a weekly cron (Mondays 06:00 UTC), satisfying "run periodically" — search engines change what they reward without any commit on our side. Reports upload as an artifact for 30 days.Runtime is about 90 seconds.
Three things setting this up revealed
The audit must build the way
pages.ymldoes. A development build has nosite.url, which leavesrel=canonicalrelative androbots.txtmissing its sitemap line. Lighthouse scored those pages 0.83 while production scored 100 — a pure false alarm. The workflow builds withJEKYLL_ENV=productionand the production config.Autodiscovery silently skipped every post. Pointed at
_site, lhci collectsindex.htmlfiles only. It happily audited 25 URLs — all tag indexes, homepage, about, 404 — and zero of the twelve posts, which are exactly the pages whose SEO matters. URLs are now listed explicitly.Listing post URLs required pinning the timezone. Jekyll derives permalinks from the post date in local time, so
2019-01-13 01:23:12 +0530builds to/2019/01/12/on a UTC runner but/2019/01/13/on a machine set to IST. The same commit produced different URLs depending on where it was built.timezone: UTCmakes local builds agree with CI.What the tool then reported
Two links whose text does not describe their target:
thishereThe second was only found because posts got added to the audit list — autodiscovery would have missed it entirely.
Both reworded. Every audited page now scores 100.
Verification
./scripts/test(build + htmlproofer) also passes.Note
Two
<title>and two<meta name="description">tags per page —_includes/head.htmlhand-rolls what{% seo %}already emits — is a real defect, but Lighthouse does not flag it (document-titleonly checks a title exists). It is not tool-reported, so it is deliberately not in this PR and will get its own change.Closes #35
🤖 Generated with Claude Code